/** 
 * @file ppw
 * @brief PPW's JueYing Mind+ library.
 * @n This is a MindPlus graphics programming extension for PPW's JueYing intelligent vehicle.
 * 
 * @copyright    PPW,2024.01
 * @copyright    MIT Lesser General Public License
 * 
 * @author [email](info@pinpinwa.cn)
 * @date  2024-01-05
*/

//% color="#339999" iconWith=50 iconHeight=40
namespace jueying{

    //--------- 以下为电机控制代码块 ---------//
    //% block="JueYing [RUN] Speed [SPEED]" blockType="command"
    //% RUN.shadow="dropdown" RUN.options="RUN"
    //% SPEED.shadow="range" SPEED.params.min=0 SPEED.params.max=255 SPEED.defl=100
    export function JY_Run(parameter:any, block:any){
        let run = parameter.RUN.code;
        let speed = parameter.SPEED.code;

        Generator.addInclude("includeJueying", "#include <Jueying.h>", true);
        Generator.addObject(`calssJueying`, `Jueying`, `myJueying`,true);
        Generator.addSetup(`iniPin`, `myJueying.initialPin();`, true);

        Generator.addCode(`myJueying.jueyingRun(${run},${speed});`);

    }

    //% block="[MOTOR] Motor Run Speed [SPEED] Dir [DIR]" blockType="command"
    //% MOTOR.shadow="dropdown" MOTOR.options="MOTOR"
    //% SPEED.shadow="range" SPEED.params.min=0 SPEED.params.max=255 SPEED.defl=100
    //% DIR.shadow="dropdown" DIR.options="DIR"
    export function JY_MotorRun(parameter:any, block:any){
        let motor = parameter.MOTOR.code;
        let speed = parameter.SPEED.code;
        let dir = parameter.DIR.code;

        Generator.addInclude("includeJueying", "#include <Jueying.h>", true);
        Generator.addObject(`calssJueying`, `Jueying`, `myJueying`,true);
        Generator.addSetup(`iniPin`, `myJueying.initialPin();`, true);

        Generator.addCode(`myJueying.motorRun(${motor}, ${dir}, ${speed});`);


    }

    //% block="[MOTOR] Motor Stop" blockType="command"
    //% MOTOR.shadow="dropdown" MOTOR.options="MOTOR"
    export function JY_MotorStop(parameter:any, block:any){
        let motor = parameter.MOTOR.code;

        Generator.addInclude("includeJueying", "#include <Jueying.h>", true);
        Generator.addObject(`calssJueying`, `Jueying`, `myJueying`,true);
        Generator.addSetup(`iniPin`, `myJueying.initialPin();`, true);

        Generator.addCode(`myJueying.motorStop(${motor});`)
    }

    //--------- 以下为巡线传感器代码块(阈值可定义) ---------//
    //% block="Line Tracking Sensor Status [STATUS] @ [THRESHOLD]" blockType="boolean"
    //% STATUS.shadow="dropdown" STATUS.options="STATUS"
    //% THRESHOLD.shadow="range" THRESHOLD.params.min=0 THRESHOLD.params.max=1023 THRESHOLD.defl=700
    export function JY_Status(parameter:any, block:any){
        let status = parameter.STATUS.code;
        let threshold = parameter.THRESHOLD.code;

        Generator.addInclude("includeJueying", "#include <Jueying.h>", true);
        Generator.addObject(`calssJueying`, `Jueying`, `myJueying`,true);
        Generator.addSetup(`iniPin`, `myJueying.initialPin();`, true);

        Generator.addCode(`myJueying.isIrStatus(${status},${threshold})`);

    }

    //--------- 以下为返回3路巡线传感器值代码块 ---------//
    //% block="Get Tracking Sensor Value @ [THRESHOLD]" blockType="reporter"
    //% THRESHOLD.shadow="range" THRESHOLD.params.min=0 THRESHOLD.params.max=1023 THRESHOLD.defl=700
    export function JY_Get_tsValue(parameter:any, block:any){
        let threshold = parameter.THRESHOLD.code;
        
        Generator.addInclude("includeJueying", "#include <Jueying.h>", true);
        Generator.addObject(`calssJueying`, `Jueying`, `myJueying`,true);
        Generator.addSetup(`iniPin`, `myJueying.initialPin();`, true);

        Generator.addCode(`myJueying.getIrStatus(${threshold})`);
    }


    //--------- 以下为 C32 超声波测距模块代码块 ---------//
    //% block="Read Ultrasonic Distance (CM)" blockType="reporter"
    export function JY_readUltrasonicDistance(parameter:any, block:any){
        Generator.addInclude("includeJueying", "#include <Jueying.h>", true);
        Generator.addObject(`calssJueying`, `Jueying`, `myJueying`,true);
        Generator.addSetup(`iniPin`, `myJueying.initialPin();`, true);

        Generator.addCode(`myJueying.e9t8UltraDis()`);
    }

    //--------- 以下为蜂鸣器驱动代码块 ---------//
    //% block="Play Tone [NOTE] Beat [BEAT]" blockType="command"
    //% NOTE.shadow="note" NOTE.defl=247
    //% BEAT.shadow="dropdownRound" BEAT.options="JY_BEAT"
    export function playTone(parameter:any, block:any){
        let tone = parameter.NOTE.code;
        let beat = parameter.BEAT.code;

        Generator.addInclude("includeDFlibs", "#include <DFRobot_Libraries.h>", true);
        Generator.addObject(`calssDFtone`, `DFRobot_Tone`, `myTone`,true);

        Generator.addCode(`myTone.play(13, ${tone}, ${beat});`);
    }


    //--------- 以下为舵机控制代码块 ---------//
    //% block="Servo [SERVO] Angle [VALUE]" blockType="command"
    //% SERVO.shadow="dropdown" SERVO.options="SERVO"
    //% VALUE.shadow="angle" VALUE.params.edge=1
    export function setServoAngle(parameter:any, block:any){
        let servo = parameter.SERVO.code;
        let value = parameter.VALUE.code;

        Generator.addInclude("includeServo", "#include <DFRobot_Servo.h>", true);
        if(servo==1){
            Generator.addObject(`classServo1`, `Servo`, `myServo1`);
            Generator.addSetup(`attachServoPin0`, `myServo1.attach(0);`);
        }
        if(servo==2){
            Generator.addObject(`classServo2`, `Servo`, `myServo2`);
            Generator.addSetup(`attachServoPin1`, `myServo2.attach(1);`);
        }
        

        Generator.addCode(`myServo${servo}.angle(abs(${value}));`);
    }
    
    //--------- 以下为幻彩氛围灯代码块 ---------//
    //% block="RGB [LED_START]to[LED_END] Show [COLOR_PALETTE]" blockType="command"
    //% LED_START.shadow="range" LED_START.params.min=1 LED_START.params.max=4 LED_START.defl=1
    //% LED_END.shadow="range" LED_END.params.min=1 LED_END.params.max=4 LED_END.defl=1
    //% COLOR_PALETTE.shadow="colorPalette" 
    export function setRangeColor(parameter:any, block:any){
        let led_start = parameter.LED_START.code;
        let led_end = parameter.LED_END.code;
        let color_palette = parameter.COLOR_PALETTE.code;

        Generator.addInclude("includeNeoPixel", "#include <DFRobot_NeoPixel.h>", true);
        Generator.addObject(`calssNeoPixel`, `DFRobot_NeoPixel`, `myNeoPixel`,true);
        Generator.addSetup(`iniNeoPixel`, `myNeoPixel.begin(11, 4);`,true);

        Generator.addCode(`myNeoPixel.setRangeColor((${led_start-1}), ${led_end-1}, ${color_palette});`);
    }

    //% block="Clear All RGB LEDs" blockType="command"
    export function clearAllRGB(parameter:any, block:any){

        Generator.addInclude("includeNeoPixel", "#include <DFRobot_NeoPixel.h>", true);
        Generator.addObject(`calssNeoPixel`, `DFRobot_NeoPixel`, `myNeoPixel`,true);
        Generator.addSetup(`iniNeoPixel`, `myNeoPixel.begin(11, 4);`,true);

        Generator.addCode(`myNeoPixel.clear();`);
    }
    /*******
    //--------- 以下为ADAFRUIT幻彩氛围灯代码块 ---------//
    //% block="ADARGB [LED_NUMBER] Show [COLOR_PALETTE]" blockType="command"
    //% LED_NUMBER.shadow="range" LED_NUMBER.params.min=1 LED_NUMBER.params.max=4 LED_NUMBER.defl=1    //% COLOR_PALETTE.shadow="colorPalette" 
    export function setPixelColor(parameter:any, block:any){
        let led_number = parameter.LED_NUMBER.code;
        let color_palette = parameter.COLOR_PALETTE.code;

        Generator.addInclude("includeAdaNeoPixel", "#include <Adafruit_NeoPixel.h>", true);
        Generator.addObject(`calssAdaNeoPixel`, `Adafruit_NeoPixel`, `myAdaNeoPixel=Adafruit_NeoPixel(4,11,NEO_GRB + NEO_KHZ800);`,true);
        //Generator.addSetup(`iniNeoPixel`, `myNeoPixel.begin ;`,true);
        Generator.addSetup(`myAdaNeoPixel`, `myAdaNeoPixel.begin();`,true);
        //Generator.addCode(`myAdaNeoPixel.setPixelColor((${led_start-1}), ${led_end-1}, ${color_palette});`);

        Generator.addCode(`myAdaNeoPixel.setPixelColor((${led_number}-1), ${color_palette});`);

        //Generator.addCode(`myAdaNeoPixel.show();`);
    }

    //% block="RGB Show" blockType="command"
    export function showRGB(parameter:any, block:any){

        Generator.addInclude("includeAdaNeoPixel", "#include <Adafruit_NeoPixel.h>", true);
        Generator.addObject(`calssAdaNeoPixel`, `Adafruit_NeoPixel`, `myAdaNeoPixel=Adafruit_NeoPixel(4,11,NEO_GRB + NEO_KHZ800);`,true);
        //Generator.addSetup(`iniNeoPixel`, `myNeoPixel.begin ;`,true);
        Generator.addSetup(`myAdaNeoPixel`, `myAdaNeoPixel.begin();`,true);

        Generator.addCode(`myAdaNeoPixel.show();`);
    }
    ********/

    //--------- 以下为红外遥控接收代码块 ---------//
    let irpin = `10`;
    let irObject = `IrReceiver`;

    //% block="IR Data Availabe?" blockType=boolean
    export function isIrData(parameter:any, block:any){
        Generator.addInclude("includeIrReceiver", `#include <IRremote.h>\n#define DECODE_NEC\n#define RECV_PIN 10`,true);
        Generator.addSetup(`${irObject}.enableIRIn`, `${irObject}.begin(${irpin});`,true);
        Generator.addCode(`${irObject}.decode()`);
        
    }

    //% block="Received IR Data" blockType=reporter
    export function readIrData(parameter:any, block:any){

        Generator.addInclude("includeIrReceiver", `#include <IRremote.h>\n#define DECODE_NEC\n#define RECV_PIN 10`,true);
        Generator.addSetup(`${irObject}.enableIRIn`, `${irObject}.begin(${irpin});`,true);
        

        Generator.addCode(`${irObject}.decodedIRData.command`)
        
        
    }
    
    //% block="Resume Read IR Data" blockType="command"
    export function readIRResume(parameter: any, block: any) {
        Generator.addInclude("includeIrReceiver", `#include <IRremote.h>\n#define DECODE_NEC\n#define RECV_PIN 10`,true);
        Generator.addSetup(`${irObject}.enableIRIn`, `${irObject}.begin(${irpin});`,true);
        Generator.addCode(`${irObject}.resume();`);
    }
    
    //% block="IR Remote [KEY] Value" blockType="reporter"
    //% KEY.shadow="dropdown" KEY.options="20KEY_VALUE"
    export function value20Key(parameter:any, block:any){
        let value_key = parameter.KEY.code;
        Generator.addCode(`${value_key}`);
    }

    //--------- 以下为 C81 OLED 显示屏模块代码块 ---------//
 /**
  * 省略OLED初始化代码块作为一条单独的代码块
    //% block="OLED Display Init Address 0x3C" blockType="command"
    export function oledInitial(parameter: any, block: any) {
        Generator.addInclude(`Include_DFRobot_SSD1306_I2C`, `#include <DFRobot_SSD1306_I2C.h>`,true);
        Generator.addObject(`DFRobot_SSD1306_I2C`, `DFRobot_SSD1306_I2C`, `myOLED;`,true);
        Generator.addSetup(`myOLED.begin`, `myOLED.begin(0x3c);`,true);
    }
 *
**/

    //% block="OLED Display [LINESTRING] in Line [LINE]" blockType="command"
    //% LINE.shadow="range"   LINE.params.min=1    LINE.params.max=4    LINE.defl=1
    //% LINESTRING.shadow="string"   LINESTRING.defl="Hello, Jueying" 
    export function oledShowLine(parameter: any, block: any) {
        let line = parameter.LINE.code;
        let str = parameter.LINESTRING.code;
        Generator.addInclude(`Include_DFRobot_SSD1306_I2C`, `#include <DFRobot_SSD1306_I2C.h>`,true);
        Generator.addObject(`DFRobot_SSD1306_I2C`, `DFRobot_SSD1306_I2C`, `myOLED;`,true);
        Generator.addSetup(`myOLED.begin`, `myOLED.begin(0x3c);`,true);
        Generator.addCode(`myOLED.setCursorLine(${line});\n  myOLED.printLine(${str});`);
    }

    //% block="OLED Display [XYSTRING] at Position X:[X] Y:[Y]" blockType="command"
    //% X.shadow="range"   X.params.min=0    X.params.max=127    X.defl=0
    //% Y.shadow="range"   Y.params.min=1    Y.params.max=4    Y.defl=1
    //% XYSTRING.shadow="string"   XYSTRING.defl="Hi, Jueying"
    export function oledShowCursor(parameter: any, block: any) {
        let x = parameter.X.code;
        let y = parameter.Y.code;
        let xystr = parameter.XYSTRING.code;
        Generator.addInclude(`Include_DFRobot_SSD1306_I2C`, `#include <DFRobot_SSD1306_I2C.h>`,true);
        Generator.addObject(`DFRobot_SSD1306_I2C`, `DFRobot_SSD1306_I2C`, `myOLED;`,true);
        Generator.addSetup(`myOLED.begin`, `myOLED.begin(0x3c);`,true);
        Generator.addCode(`myOLED.setCursor(${x},${y}-1);\n  myOLED.print(${xystr});`);
    }

    
    //% block="OLED Clear" blockType="command"
    export function oledClear(parameter: any, block: any) {
        Generator.addInclude(`Include_DFRobot_SSD1306_I2C`, `#include <DFRobot_SSD1306_I2C.h>`,true);
        Generator.addObject(`DFRobot_SSD1306_I2C`, `DFRobot_SSD1306_I2C`, `myOLED;`,true);
        Generator.addSetup(`myOLED.begin`, `myOLED.begin(0x3c);`,true);
        Generator.addCode(`myOLED.fillScreen(0);`);
    }

    //--------- 以下为 JS01 手柄代码块 ---------//
    //% block="Jostick Button [JSBTN] is Pressed?" blockType="boolean"
    //% JSBTN.shadow="dropdown" JSBTN.options="JSBTN"
    export function JS_Status(parameter:any, block:any){
        let jsbtn = parameter.JSBTN.code;

        Generator.addInclude("includeJueying", "#include <Jueying.h>", true);
        Generator.addObject(`calssJueying`, `Jueying`, `myJueying`,true);
        Generator.addSetup(`iniPin`, `myJueying.initialPin();`, true);

        Generator.addCode(`myJueying.isJsBtnPressed(${jsbtn})`);

    }


}